<?php
/**
 * CreateTime: 2023/6/12 14:46
 */

namespace App\Func;

use App\Models\MeLawCase\MeLawCase;
use App\Models\Staff\StaffModel;

class MeLawCaseAllocation
{

    private function allocationTypeMoney($cases,$num_workers){

    }

    private function allocationTypeNumber($cases,$num_workers){

    }

    private function hAllocationTypeMoneyNumber($cases,$workers){
        // 对$cases数组按照"money"键的值（即案件金额）进行降序排序
        usort($cases, function($a, $b){
            return $a['money'] - $b['money'];
        });
        $lawLen = count($workers);
        $caseLen = 0;
        $flag = true;
        while(true){

            for ($lawLen;$lawLen>=0;$lawLen--){
                $flag = false;
            }
        }


    }


    /**
     * 当前返回
     * @param $cases - 案件列表
     * @param $workers - 调解员列表
     * @param $staffIdMap - mediator_list assigned_cases
     * @return array
     */
    private function allocationTypeMoneyNumber($cases,$workers,$staffIdMap){
        // 对$cases数组按照"money"键的值（即案件金额）进行升序排序
        usort($cases, function($a, $b){
            return $a['money'] - $b['money'];
        });

        // 使用0初始化金额数量和案例数
        $worker_stats = array();
        foreach ($workers as $worker_id) {
            $worker_stats[$worker_id] = array("amount" => 0, "num_cases" => 0);
        }

        // 计算每个工人的平均金额
        $total_amount = array_sum(array_column($cases, 'money'));
        $num_workers = count($workers);
        $avg_amount = $total_amount / $num_workers;

        // 将案例分配给工作人员
        $assigned_cases = array();
        $current_worker_index = 0;


        // 固定洗牌算法重置键值
        $workers = $this->shuffleArray($workers,count($workers));

        foreach ($cases as $case) {
            // 获取当前员工的ID
            $current_worker = $workers[$current_worker_index];

            // 检查当前工作人员是否已分配过多
            if ($worker_stats[$current_worker]["amount"] > $avg_amount) {
                // 以循环方式分配给下一个工人
                $current_worker_index = ($current_worker_index + 1) % $num_workers;
                $current_worker = $workers[$current_worker_index];
            }

            // 将案例分配给当前工作人员
            $worker_stats[$current_worker]["amount"] = bcadd($worker_stats[$current_worker]["amount"],$case["money"],3);
            $worker_stats[$current_worker]["num_cases"] += 1;
            $assigned_cases[$case["lawCaseId"]] = $current_worker;

            // 移动到下一个工人
            // 如果当前要分配给的员工不是数组中的最后一个员工，则直接将索引加1即可。例如，如果当前索引为1，有三个员工，则结果为2。
            // 但是，如果当前要分配给的员工已经是数组中的最后一个员工，就需要让索引回到数组开头，重新从第一个员工开始分配。例如，如果当前索引为2，有三个员工，则结果为0。
            // 通过使用取模运算符，我们可以将上述两种情况统一起来，让索引在达到数组末尾时自动回到数组开头。例如，如果当前索引为2，有三个员工，则结果为2 % 3 = 2，也就是回到了数组开头。
            $current_worker_index = ($current_worker_index + 1) % $num_workers;
        }

        // Print out amounts and number of cases for each worker
        $resMediatorList = [];
        foreach ($workers as $worker_id) {
            $resMediatorList[] = [
                'mediator_id' => $worker_id,
                'mediator_name' => $staffIdMap[$worker_id],
                'amount_of_money' => $worker_stats[$worker_id]["amount"],
                'cases_numbers' => $worker_stats[$worker_id]["num_cases"],
            ];
        }
        return [
            'mediator_list' => $resMediatorList
        ];
    }

    function shuffleArray($array,$seed) {
        mt_srand($seed); // 设置随机数种子
        $length = count($array);

        for ($i = $length - 1; $i > 0; $i--) {
            $j = random_int(0, $i);
            [$array[$i], $array[$j]] = [$array[$j], $array[$i]];
        }

        return $array;
    }


    public function allocationTypeMoneyNumberGetPost($cases,$workers){
        // 对$cases数组按照"money"键的值（即案件金额）进行降序排序
        usort($cases, function($a, $b){
            return $b['money'] - $a['money'];
        });
        // 固定洗牌算法重置键值
        $workers = $this->shuffleArray($workers,count($workers));
        // 使用0初始化金额数量和案例数
        $worker_stats = array();
        foreach ($workers as $worker_id) {
            $worker_stats[$worker_id] = array("amount" => 0, "num_cases" => 0);
        }

        // 计算每个工人的平均金额
        $total_amount = array_sum(array_column($cases, 'money'));
        $num_workers = count($workers);
        $avg_amount = $total_amount / $num_workers;

        // 将案例分配给工作人员
        $assigned_cases = array();
        $current_worker_index = 0;
        foreach ($cases as $case) {
            // 获取当前员工的ID
            $current_worker = $workers[$current_worker_index];

            // 检查当前工作人员是否已分配过多
            if ($worker_stats[$current_worker]["amount"] > $avg_amount) {
                // 以循环方式分配给下一个工人
                $current_worker_index = ($current_worker_index + 1) % $num_workers;
                $current_worker = $workers[$current_worker_index];
            }

            // 将案例分配给当前工作人员
            $worker_stats[$current_worker]["amount"] = bcadd($worker_stats[$current_worker]["amount"],$case["money"],3);
            $worker_stats[$current_worker]["num_cases"] += 1;
            $assigned_cases[$case["lawCaseId"]] = $current_worker;

            // 移动到下一个工人
            // 如果当前要分配给的员工不是数组中的最后一个员工，则直接将索引加1即可。例如，如果当前索引为1，有三个员工，则结果为2。
            // 但是，如果当前要分配给的员工已经是数组中的最后一个员工，就需要让索引回到数组开头，重新从第一个员工开始分配。例如，如果当前索引为2，有三个员工，则结果为0。
            // 通过使用取模运算符，我们可以将上述两种情况统一起来，让索引在达到数组末尾时自动回到数组开头。例如，如果当前索引为2，有三个员工，则结果为2 % 3 = 2，也就是回到了数组开头。
            $current_worker_index = ($current_worker_index + 1) % $num_workers;
        }
        return $assigned_cases;
    }

    public function lawCaseAllocation($type = 1,$cases,$num_workers){
        $staffModel = new StaffModel();
        $staffAll = $staffModel->getAllStaffBySelect(['staff_id','staff_name']);
        $staffIdMap = array_column($staffAll->toArray(),'staff_name','staff_id');
        switch ($type){
            case 1:
                return $this->allocationTypeMoneyNumber($cases,$num_workers,$staffIdMap);
            case 2:
                return $this->allocationTypeNumber($cases,$num_workers);
            case 3:
                return $this->allocationTypeMoney($cases,$num_workers);
        }
    }
}